<template>
  <div v-if="config && config !== null" class="container" :key="key">
    <div v-if="config.type == 'comp'" class="cell-tabs">
      <div
        class="cell-tabs-header"
        :style="{ display: tabDisplay ? 'flex' : 'none' }"
        ref="tabBar"
      >
        <div class="tabs">
          <div
            @click="tabbarClick(item.cellID)"
            class="tab"
            v-for="(item, idx) of tabsList"
            :key="idx"
            :style="{
              background: currentTabIndex == idx ? '#fff' : 'transparent'
            }"
          >
            <i-input
              @on-focus="tabClick(idx)"
              :index="idx"
              @on-blur="tabTitleChange($event, idx)"
              :value="$srv.getI18nBySrv(item.label)"
            >
            </i-input>

            <Icon type="md-close" @click="tabRemove(idx)" />
          </div>
        </div>
        <div class="add-tabs-btn" @click="tabAdd">
          <Icon type="md-add" />
        </div>
      </div>
      <div class="cell-tabs-content" ref="cellContent">
        <div
          class="cover"
          :style="{
            width: tabsList.length * 100 + '%',
            transform:
              'translateX(' + (-currentTabIndex * 100) / tabsList.length + '%)'
          }"
        >
          <div
            class="cell"
            v-for="(item, idx) of tabsList"
            :key="idx"
            @mouseleave="mouseLeave"
            @drop="compDrop($event, idx)"
            @dragover="allowDrop"
            @dragenter="dragEnter"
            @dragleave="dragLeave"
          >
            <LayoutEditor
              v-if="!$srv.noValue(item.config)"
              :config="item.config"
              :compBoxInfo="GT_compBoxInfo"
            ></LayoutEditor>

            <span
              v-else
              @contextmenu.prevent="rightClick($event, idx, item.compName)"
              class="cell-id"
              @click="cellIdClicked(idx, $event)"
            >
              <i
                :class="{
                  cellChecked: isCellChecked,
                  unCellChecked: !isCellChecked
                }"
                ref="box"
              >
                {{ tabDisplay ? item.cellID : config.name }}
              </i>
              <b>
                {{
                  item.compName
                    ? $srv.getI18nByPath(
                        'system.components.' + item.compName.toLowerCase()
                      )
                    : ''
                }}
              </b>
            </span>
          </div>
        </div>
      </div>
    </div>
    <!-- 递归 -->
    <Split
      v-else-if="config.type == 'layout'"
      v-model="config.config.value"
      :mode="config.config.mode == 'h' ? 'horizontal' : 'vertical'"
      min="17px"
      max="17px"
    >
      <div
        :slot="config.config.mode == 'h' ? 'left' : 'top'"
        class="no-padding"
      >
        <LayoutEditor
          :config="config.config.first"
          :compBoxInfo="GT_compBoxInfo"
        ></LayoutEditor>
      </div>
      <div
        :slot="config.config.mode == 'h' ? 'right' : 'bottom'"
        class="no-padding"
      >
        <LayoutEditor
          :config="config.config.second"
          :compBoxInfo="GT_compBoxInfo"
        ></LayoutEditor>
      </div>
    </Split>
  </div>
</template>

<script lang="ts">
import { N_oSetupPanel } from '@/types';
import {
  T_srv,
  Tsrv,
  ifs,
  ts,
  vue,
  I_command,
  COMP_BASE_TAB_NAME
} from './config';

@T_srv.comp({ name: 'LayoutEditor' })
export default class LayoutEditor extends vue {
  @T_srv.prop({ default: () => {}, required: true, type: Object })
  private config!: any;

  @T_srv.ref('tabBar') readonly tabBarRef: any;

  @T_srv.ref('cellContent') readonly cellContentRef: any;

  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  /* 组件名 */
  private G_compName: string = 'LayoutEditor';

  private name: string = 'LayoutEditor';

  /* 组件箱信息对象 */
  private GT_compBoxInfo: ifs.I_compBoxInfo;

  /* 组件箱对象 */
  private GT_compBox: ifs.I_compBox;

  /* 组件箱识别ID */
  private G_compID: string;

  // 是否装填了BaseTab
  private tabDisplay: boolean = false;

  // 当前选择的Tab
  private currentTabIndex: number = 0;

  private GT_name: string;

  private GT_command: I_command;

  public isCellChecked: boolean = false;

  private oSetupPanel: N_oSetupPanel.oSetupPanel = null;

  // 重复组件+id分别
  private ID: string = Tsrv.utils.custUUID(6);

  // Tabs的配置信息
  private tabsList: N_oSetupPanel.I_editorTabsList[] = [];

  // private compDownt: boolean = true; // 是否模板在修改，如果修改过就不能移入comp组件clr

  private num: number = 0;

  private configbak: any;

  private showMsgDropdown: boolean = false;

  private layoutSelectIdx: number = null;

  private key: string = Tsrv.utils.custUUID(8);

  private layoutisadd: boolean = false;

  private tabsID: string = '';

  created() {
    // 如果父组件没有传参，那就产生一个
    this.GT_name = this.config.name;
    this.GT_compBoxInfo = Tsrv.getCompInfo(this.compBoxInfo);
    this.G_compID = this.GT_compBoxInfo.compID;
    this.GT_compBox = this.GT_compBoxInfo.TcompBox;
    this.GT_command = this.GT_compBox.getCompMergeName(
      this.G_compID,
      'oSetupPanelCMD'
    );
    this.oSetupPanel = this.GT_compBox.getCompMergeName(
      this.G_compID,
      'oSetupPanel'
    );
    this.init();
  }

  private init() {
    this.tabsID = Tsrv.noValue(this.config.name) ? '1' : this.config.name;
    if (this.config?.config?.name === COMP_BASE_TAB_NAME) {
      this.tabDisplay = true;
      this.config.config.config.panels.forEach((el, key) => {
        if (!Tsrv.noValue(el.content.config?.first)) {
          this.splitTabContianer(el);
        } else {
          this.tabsList.push({
            label: el.label,
            compName: el.content.name,
            // cellID: key + 1,
            cellID:
              typeof el.content === 'string' ? el.content : el.content.cellID,
            config: undefined,
            isContainer: false,
            tabsID: this.tabsID
          });
        }
      });
    } else {
      const o = this.GT_command.Tsetup.configStore.all[this.config.name];
      this.tabsList.push({
        label: '', // tab的标签，如果为空，则没有BaseTab组件
        compName: Tsrv.noValue(o) ? '' : o.name, // 模组的名称，如BaseGrid、BaseTab，如果为空，则没有任何组件
        cellID: Tsrv.noValue(this.config.name)
          ? '1-1'
          : `${this.config.name}-1`, // tabs内的cellID，tabs内唯一
        config: undefined, // 子组件
        isContainer: false,
        tabsID: this.tabsID
      });
    }
  }

  destroyed() {
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);
    /* 如果父组件传入的compBoxInfo则删除本文件产生的引用,反之是本组件产生的ID统一删除 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
  }

  mounted() {
    this.G_compName = `${this.G_compName}_${this.config.name ?? this.ID}`;

    this.$emit('compBoxInfo', this.GT_compBoxInfo);
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);

    this.oSetupPanel.initCompIDList(this.tabsList);
  }

  public onCellSelected(cellID) {
    // this.handleCellSelected(cellID);
    const comps = this.GT_compBox.getCompsRegexMathName(
      `^${this.G_compID}_LayoutEditor`
    );
    if (!Tsrv.noValue(comps)) {
      comps.forEach(el => {
        el.comp.handleCellSelected(cellID);
      });
    }

    this.oSetupPanel.setupOnCellSelected(cellID);
  }

  public handleCellSelected(cellID) {
    if (this.tabBarRef !== undefined) {
      this.tabBarRef.style.backgroundColor = '#f1f1f1';
    }
    this.isCellChecked = false;
  }

  public onCellFilled(type, componentID, cellID) {
    this.oSetupPanel.setupOnCellFilled(type, componentID, cellID);
  }

  public processCompConfig(config) {
    if (this.config) {
      if (this.tabDisplay) {
        this.tabsList.forEach(el => {
          // if (!config[`${this.config.name}-${el.cellID}`]) {
          if (!config[`${el.cellID}`]) {
            el.compName = '';
          }
        });
        if (!config[this.config.name]) {
          this.resetCurrentBox();
        }
      } else {
        if (!config[this.config.name]) {
          this.resetCurrentBox();
        } else {
          this.tabsList = [];
          const myConfig = config[this.config.name];
          if (myConfig.name === COMP_BASE_TAB_NAME) {
            this.tabDisplay = true;
            myConfig.config.panels.forEach((el, key) => {
              if (!Tsrv.noValue(el.content.config?.first)) {
                this.splitTabContianer(el);
              } else {
                this.tabsList.push({
                  label: el.label,
                  compName: config[el.content].name,
                  // cellID: key + 1,
                  cellID: this.getTabsCellID(key),
                  config: undefined,
                  isContainer: false,
                  tabsID: this.tabsID
                });
              }
            });
          } else {
            this.tabsList = [
              {
                label: '',
                compName: myConfig.name,
                cellID: this.getTabsCellID(),
                config: undefined,
                isContainer: false,
                tabsID: this.tabsID
              }
            ];
          }
          this.tabsList.forEach((el, idx) => {
            if (!el.isContainer) {
              this.oSetupPanel.updateCompIDList(
                this.tabsID,
                idx,
                this.tabsList
              );
            }
          });
        }
      }
    }
  }

  private splitTabContianer(tabPanelEl) {
    if (!Tsrv.noValue(tabPanelEl.content.config?.first)) {
      this.tabsList.push({
        label: tabPanelEl.label,
        compName: '',
        // cellID: key + 1,
        cellID: tabPanelEl.content.cellID, //
        config: tabPanelEl.content,
        isContainer: true,
        tabsID: tabPanelEl.content.cellID
      });
    }
  }

  // 重置当前box
  public resetCurrentBox() {
    this.tabsList = [
      {
        label: '',
        compName: '',
        cellID: this.getTabsCellID(),
        config: undefined,
        isContainer: false,
        tabsID: this.tabsID
      }
    ];
    this.tabDisplay = false;
    this.currentTabIndex = 0;
  }

  /*
    /* tabs的事件
    */
  // tab点击，改变样式
  public tabClick(index) {
    this.currentTabIndex = index;
  }

  // tabbar点击，显示tabbar的配置信息
  public tabbarClick(cellID: string) {
    this.onCellSelected(cellID);

    if (this.tabBarRef !== undefined) {
      this.tabBarRef.style.backgroundColor = 'var(--default-hover-font-color)';
    }
  }

  // 添加新的Tab
  public tabAdd() {
    // 设置tabbar的选中状态
    this.onCellSelected(this.config.name);
    // 更新tabsList
    this.tabsList.push({
      // label: "新标签",
      label: Tsrv.getI18nByPath('others.newlabel') as string,
      compName: '',
      // cellID: this.tabsList[this.tabsList.length - 1].cellID + 1, // 新添加的tab的CellID顺延
      cellID: this.getTabsCellID(this.tabsList.length), // 新添加的tab的CellID顺延
      config: undefined,
      isContainer: false,
      tabsID: this.tabsID
    });
    this.currentTabIndex = this.tabsList.length - 1; // 更新选中的tab为新添加的tab
    // 滚动到底部
    const scroll = this.tabBarRef.children[0];
    this.$nextTick(() => {
      if (scroll.scrollWidth > scroll.clientWidth) {
        scroll.scrollLeft = scroll.scrollWidth;
      }
    });
  }

  public tabRemove(index) {
    // 设置tabbar的选中状态
    this.onCellSelected(this.config.name);
    // 更新tabsList
    const length = this.tabsList.length;
    this.tabsList.splice(index, 1);
    // 设置当前选中的tab
    if (index + 1 < length) {
      this.currentTabIndex = index;
      this.oSetupPanel.updateCompIDList(
        this.tabsID,
        this.currentTabIndex,
        this.tabsList
      );
    } else {
      if (index !== 0) {
        this.currentTabIndex = index - 1;
        this.oSetupPanel.updateCompIDList(
          this.tabsID,
          this.currentTabIndex,
          this.tabsList
        );
      } else {
        this.oSetupPanel.setupResetCell();
      }
    }
  }

  // tab的Label修改
  public tabTitleChange(val, index) {
    const newValue = val.target.value;
    this.tabsList[index].label = newValue;

    if (this.tabsList[index].isContainer) {
      this.oSetupPanel.configStore.all[this.tabsID].config.panels[
        index
      ].label = newValue;
      this.GT_command.Tsetup.configStore.all[this.tabsID].config.panels[
        index
      ].label = newValue;
    }

    // 更新组件ID列表
    this.oSetupPanel.updateCompIDList(this.tabsID, index, this.tabsList);
  }

  /*
    /* cell的事件
    */
  // cell点击，显示cell的配置信息
  public cellIdClicked(idx, e) {
    this.GT_command.getMainTopCardBox().toggleHandler(false);
    this.closeContextMenu();
    // 获取当前点击的是tab里哪一个组件
    // const index = e.currentTarget.attributes.index.value;
    // // 当前box的ID，如果有basetab，则box-id为1-1模式
    const boxID = this.tabDisplay
      ? `${this.tabsList[idx].cellID}`
      : this.config.name;

    // 广播点击事件，其他cell/tabbar的选中状态消失，并显示cell的属性
    this.onCellSelected(boxID);
    // 激活当前cell的选中状态
    this.isCellChecked = true;
  }

  /*
    /* drag的事件
    */
  // drop处理
  public compDrop(e, index) {
    e.stopPropagation(); // 阻止事件冒泡到B
    // 只有不是新增的模板才能拖下组件clr
    if (this.oSetupPanel.layoutisadd) {
      return;
    }
    // 只有不修改界面的才可以移入组件clr
    e.preventDefault(); // preventDefault() 方法阻止元素发生默认的行为（例如，当点击提交按钮时阻止对表单的提交）
    // 获取drop的组件信息
    const data = e.dataTransfer.getData('compname_moduleid');
    // drop到哪一个cell
    const currentCell = this.tabsList[index];
    e.currentTarget.style.background = '#fff';
    if (data) {
      // 获取组件的name，例如basegrid，basetab
      // 获取组件的编号id，如basegrid是1，basetab是2
      const dataArr = data.split('_');
      const type = dataArr[0];
      const moduleID = dataArr[2];
      const compName = dataArr[1];
      // 如果组件为basetab
      if (compName === COMP_BASE_TAB_NAME) {
        // 如果不存在basetab，则继续，否则不进行操作
        if (!this.tabDisplay) {
          // 显示tabbar
          this.tabDisplay = true;
          // 重置第一个组件为空
          currentCell.label = Tsrv.getI18nByPath('others.newlabel') as string;
          currentCell.compName = '';
          currentCell.cellID = this.getTabsCellID();
          // 发送组件填充事件，组件编号id，和boxid
          this.onCellFilled(type, moduleID, this.config.name);
          // 选中tabbar
          this.onCellSelected(this.config.name);
          if (this.tabBarRef !== undefined) {
            this.tabBarRef.style.backgroundColor =
              'var(--default-hover-font-color)';
          }
        }
      } else {
        // 如果组件不为basetab
        // 如果已有basetab
        if (!this.tabDisplay) {
          // 写入信息
          currentCell.compName = compName;
          // const boxID = this.config.name;
          const boxID = currentCell.tabsID;
          this.onCellFilled(type, moduleID, boxID);
          this.onCellSelected(boxID);
        } else {
          currentCell.compName = compName;
          // const boxID = `${this.config.name}-${currentCell.cellID}`;
          const boxID = currentCell.cellID;
          this.onCellFilled(type, moduleID, boxID);
          this.onCellSelected(boxID);
        }
        this.isCellChecked = true;
      }
      // 更新组件ID列表
      this.oSetupPanel.updateCompIDList(
        this.tabsID,
        this.currentTabIndex,
        this.tabsList
      );
    } else {
      if (!Tsrv.utils.noValue(e.dataTransfer.getData('layout_change'))) {
        // 转发layout变动
        this.oSetupPanel.compDrop(e);
      }
    }
  }

  public addlayoutmodel(e, index: string) {}

  // 拖拽的事件处理
  public allowDrop(e) {
    // 只接受来自指定的元素进行拖拽
    if (e.dataTransfer.types.includes('compname_moduleid')) {
      e.dataTransfer.dropEffect = 'copy';
    } else {
      e.dataTransfer.dropEffect = 'none';
    }
    e.preventDefault();
  }

  public dragEnter(e) {
    e.currentTarget.style.background = 'rgba(245, 245, 245, 0.5)';
  }

  public dragLeave(e) {
    e.currentTarget.style.background = '#fff';
  }

  public handleClick(e: any) {
    const name: string = this.config.name;
    const cf = {
      mode: 'v',
      value: 0.5,
      first: {
        name,
        type: 'comp',
        config: {}
      },
      second: {
        name: String(parseInt(name, 10) + 1),
        type: 'comp',
        config: {}
      }
    };
    if (this.tabDisplay) {
      if (e === 'hsplit') {
        cf.mode = 'v';
      } else {
        cf.mode = 'h';
      }

      const cellID = `${this.tabsList[this.currentTabIndex].cellID}`;
      cf.first.name = `${cellID}-1`;
      cf.second.name = `${cellID}-2`;
      cf.first['cellID'] = `${cellID}-1`;
      cf.second['cellID'] = `${cellID}-2`;
      this.tabsList[this.currentTabIndex].compName = 'layout'; // tabs里是画布
      this.tabsList[this.currentTabIndex].isContainer = true;
      this.tabsList[this.currentTabIndex].config = {
        name: 'layout', // cellID
        type: 'layout',
        cellID,
        config: cf
      };
      this.GT_command.Tsetup.configStore.all[this.tabsID].config.panels.push({
        label: `${this.tabsList[this.currentTabIndex].label}`,
        content: this.tabsList[this.currentTabIndex].config
      });
      this.oSetupPanel.configStore.all[this.tabsID].config.panels.push({
        label: `${this.tabsList[this.currentTabIndex].label}`,
        content: this.tabsList[this.currentTabIndex].config
      });
    } else {
      this.config.name = 'layout';
      this.config.type = 'layout';
      if (e === 'hsplit') {
        cf.mode = 'v';
        this.config.config = cf;
      } else {
        cf.mode = 'h';
        this.config.config = cf;
      }
    }

    const configtt: [] = this.oSetupPanel.findConfig();
    this.num = 1;
    this.takeLayout(configtt, this.num);
  }

  private takeLayout(configp: any, n: number) {
    if (configp.type === 'layout') {
      this.takeLayout(configp.config.first, this.num);
      this.takeLayout(configp.config.second, this.num);
    } else {
      this.num = n + 1;
      configp.name = String(n);
    }
  }

  public rightClick(e: any, idx: number, compName: string) {
    // // oSetupPanel的layoutisadd是新增状态才可以拆分
    if (
      (this.oSetupPanel.layoutisadd || this.tabDisplay) &&
      Tsrv.utils.noValue(compName)
    ) {
      const list = [
        { name: 'hsplit', title: '横向拆分' },
        { name: 'lsplit', title: '纵向拆分' }
      ];
      this.GT_command.setContextMenuCallback(this.handleClick);
      this.GT_command.setGlobalContextMenuList(...list);
      this.GT_command.openGcontextMenu(this.G_compName, {
        clientX: e.clientX,
        clientY: e.clientY
      });
    }
  }

  private getTabsCellID(idx: number = NaN) {
    if (!isNaN(idx) && !Number.isInteger(idx)) {
      throw new Error('params[idx] is not an integer ');
    }
    return isNaN(idx) ? `${this.tabsID}-1` : `${this.tabsID}-${idx + 1}`;
  }

  public cellClicked() {
    this.closeContextMenu();
  }

  public closeContextMenu() {
    this.GT_command.closeGcontextMenu();
  }

  public onContextSelect(e) {
    // this.config = key;
    this.handleClick(e);
    this.GT_command.closeGcontextMenu();
  }

  public mouseLeave() {
    // this.closeContextMenu();
  }

  public dblclickGo(e: any, val: any) {
    if (this.showMsgDropdown) {
      this.showMsgDropdown = false;
    } else {
      this.showMsgDropdown = true;
    }
    if (val.length > 0) {
      this.showMsgDropdown = false;
    }
  }
}
</script>

<style scoped lang="scss">
.container {
  width: 100%;
  height: 100%;
}
.no-padding {
  height: 100%;
  width: 100%;
  padding: 0;
  background-color: #fff;
  transform: translate3d(0, 0, 0);
  overflow: hidden;
}
.cell-tabs {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  .cell-tabs-header {
    height: 50px;
    background-color: #f1f1f1;
    display: flex;
    flex-direction: row;
    cursor: pointer;
    .tabs::-webkit-scrollbar {
      /* 滚动条的宽和高 */
      width: 0px;
      height: 4px;
    }
    .tabs::-webkit-scrollbar-thumb {
      /*滚动条里面小方块*/
      border-radius: 2px;
      box-shadow: inset 0 0 2px rgba(0, 0, 0, 0.2);
      background: rgba(0, 0, 0, 0.2);
    }
    .tabs {
      width: calc(100% - 50px);
      overflow-x: auto;
      overflow-y: hidden;
      display: -webkit-box;
      .tab ::v-deep {
        line-height: 50px;
        padding: 0 10px;
        display: flex;
        flex-direction: row;
        cursor: pointer;
        input {
          height: 50px;
          width: 60px;
          border: 0;
          background-color: transparent;
          box-shadow: none;
        }
        // span {
        //   display: block;
        //   outline: none;
        //   padding: 0 5px;
        // }
        .ivu-icon {
          line-height: 50px;
        }
      }
    }
    .add-tabs-btn {
      height: 30px;
      width: 30px;
      border-radius: 100%;
      margin: 10px;
      font-size: 20px;
      text-align: center;
      line-height: 30px;
      color: #666;
      cursor: pointer;
      transition: var(--animation-hover);
    }
    .add-tabs-btn:hover {
      background-color: #eee;
    }
  }
  .cell-tabs-content {
    flex: 1;
    .cover {
      display: flex;
      flex-direction: row;
      height: 100%;
    }
  }
}
.cell {
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  // cursor: pointer;
  transition: var(--animation-hover);
  .cell-id {
    display: block;
    cursor: pointer;
    color: #666;
    font-size: 12px;
    height: 30px;
    line-height: 30px;
    transition: var(--animation-hover);
    i {
      font-style: normal;
      display: block;
      height: 30px;
      width: 150px;
      background-color: #eee;
      border-radius: 100%;
      text-align: center;
      float: left;
      margin-right: 10px;
    }
    b {
      font-size: 18px;
    }
    .cellChecked {
      background: var(--default-hover-font-color);
      color: #eee;
    }
    .unCellChecked {
      background: #eee;
      color: #000;
    }
  }
}
.cell:hover {
  background-color: rgba(245, 245, 245, 0.5) !important;
}

.ivu-split-wrapper ::v-deep {
  .ivu-split-trigger-horizontal {
    height: 3px;
    background-color: #eee;
    border: 0;
    .ivu-split-trigger-bar-con.horizontal {
      top: 0;
    }
    .ivu-split-trigger-bar {
      height: 3px;
    }
  }
  .ivu-split-trigger-vertical {
    width: 3px;
    background-color: #eee;
    border: 0;
    .ivu-split-trigger-bar-con.vertical {
      left: 0;
    }
    .ivu-split-trigger-bar {
      width: 3px;
    }
  }
  .ivu-split-trigger-bar {
    background-color: rgba(23, 35, 61, 0.35);
  }
}
</style>
